<?php

/**
 * Класс RL_RequestRouter -- разбирает URL, собирает URL из запроса.
 *
 * Считывать конфиг url map
 * Разбирать запрос пользователя в хеш массив (url -> хеш)
 * Хеш -> url
 *
 */
class RL_RequestRouter
{
	/**
	 * defaults 
	 * типы по умолчанию, чтобы не указывать 
	 * одно и тоже во всех правилах
	 * 
	 * @var array
	 */
	public $defaults = array();

	/**
	 * rules 
	 * 
	 * @var array
	 */
	private $rules  = array();

	/**
	 * Вернуть RL_Request.
	 *
	 * Если $url не указан -- считать инфу из переменных окружения ($_GET, 
	 * $_POST, ..)
	 *
	 * @param string $url -- урл
	 * @return object RL_Request
	 */
	public function mapUrl($request, $url='')
	{
		$res = $request;
		$this->matched_rule = NULL;
		// бегаем по каждому правилу, пока не совпадет
		foreach ($this->getRules() as $k => $rule) {
			if ($params = $rule->match($url)) {
				$this->matched_rule = $rule;
				break;
			}
		}

		if ($params) {
			//$request = array_merge($request, $params);
			foreach ($params as $k=>$v) {
				$request[$k] = $v;
			}

			
		} else {
			// FIXME lucky:
			// запрос не сопоставился с правилами маршрутизации
			// тут видимо должна применяться какая-то политика по умолчанию
		}

		return $request;
	}
	
	/**
	 * Получить класс-правило последнее найденное методом mapUrl
	 *
	 * @return class implements URLDescription
	 * @author Alexander Sibiryakov
	 **/
	public function getLastMatched() {
		return $this->matched_rule;
	}

	/**
	 * pack 
	 * 
	 * @param RL_Request $request 
	 * @return void
	 */
	public function pack(RL_Request $request)
	{
		$url = NULL;
		$req = $request->pack();

		// бегаем по каждому правилу, пока не совпадет
		foreach ($this->getRules() as $k => $rule) {
			
			if ($url = $rule->pack($req)) {
				break;
			}
		}

		return $url;
	}

	/**
	 * Загрузить правила разбора URL из массива
	 *
	 * @param Array $rules :: [Mapti]
	 */
	public function loadRules(Array $rules)
	{
		$this->rules =& $rules;
	}

	/**
	 * Вернуть правила разбора URL
	 */
	public function &getRules()
	{
		return $this->rules;
	}
	
	/**
	 * Добавляет у существующим новые правила
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	public function addRules(Array $rules) {
		$this->rules = array_merge($this->rules, $rules);
	}
	
	/**
	 * Вернет конкретное правило разбора URL по ключу
	 *
	 * @return void
	 * @author Alexander Sibiryakov
	 **/
	public function getRule($key)
	{
		if (isset($this->rules[$key]))
			return $this->rules[$key];
		return NULL;
	}
	
}

